package org.dromara.hm.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.dto.RoleDTO;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.ProductService;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.helper.DataPermissionHelper;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.hm.domain.HmIssueReceiptRecords;
import org.dromara.hm.domain.HmStock;
import org.dromara.hm.domain.bo.HmIssueReceiptRecordsBo;
import org.dromara.hm.domain.bo.HmStockChangeBo;
import org.dromara.hm.domain.bo.HmTodoItemsBo;
import org.dromara.hm.domain.vo.HmCustomerVo;
import org.dromara.hm.domain.vo.HmIssueReceiptRecordsVo;
import org.dromara.hm.domain.vo.HmStockVo;
import org.dromara.hm.domain.vo.HmTodoItemsVo;
import org.dromara.hm.enums.ReceiptIssueRecordTypeEnum;
import org.dromara.hm.enums.StockChangeTypeEnum;
import org.dromara.hm.enums.ToDoTypeEnum;
import org.dromara.hm.enums.TodoItemStatus;
import org.dromara.hm.mapper.HmCustomerMapper;
import org.dromara.hm.mapper.HmIssueReceiptRecordsMapper;
import org.dromara.hm.mapper.HmStockMapper;
import org.dromara.hm.service.IHmIssueReceiptRecordsService;
import org.dromara.hm.service.IHmProductService;
import org.dromara.hm.service.IHmStockService;
import org.dromara.hm.service.IHmTodoItemsService;
import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.service.ISysDeptService;
import org.dromara.system.service.ISysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 出入库记录Service业务层处理
 *
 * @author zy Hu
 * @date 2024-12-15
 */
@RequiredArgsConstructor
@Service
public class HmIssueReceiptRecordsServiceImpl implements IHmIssueReceiptRecordsService
{

    private final HmIssueReceiptRecordsMapper baseMapper;

    // 库存service
    private final IHmStockService hmStockService;

    // 代办事项service
    private final IHmTodoItemsService hmTodoItemsService;

    // 员工Service
    private final ISysUserService userService;

    // 店铺service
    private final ISysDeptService deptService;

    // 商品翻译Service
    private final ProductService productService;

    // 商品Service
    private final IHmProductService hmProductService; // 注入 IHmProductService

    // 客户Service
    private final HmCustomerMapper customerService;

    private final HmStockChangeServiceImpl hmStockChangeServiceImpl;

    /**
     * 库存记录
     */
    private final HmStockMapper stockMapper;

    /**
     * 查询出入库记录
     *
     * @param recordId 主键
     *
     * @return 出入库记录
     */
    @Override
    public HmIssueReceiptRecordsVo queryById(Long recordId)
    {
        HmIssueReceiptRecordsVo hmIssueReceiptRecordsVo = baseMapper.selectVoById(recordId);
        if (ObjectUtil.isNotNull(hmIssueReceiptRecordsVo))
        {
            if (ReceiptIssueRecordTypeEnum.EMPLOYEE_BENEFITS.getCode().equals(hmIssueReceiptRecordsVo.getRecordType()))
            {
                // 员工福利
                hmIssueReceiptRecordsVo.setEmployeeIds(Arrays.asList(hmIssueReceiptRecordsVo.getUserOrCustomerIds().split(",")));
            }
            else if (ReceiptIssueRecordTypeEnum.CUSTOMER_GIFTS.getCode().equals(hmIssueReceiptRecordsVo.getRecordType()))
            {
                // 客户赠品
                hmIssueReceiptRecordsVo.setCustomerIds(Arrays.asList(hmIssueReceiptRecordsVo.getUserOrCustomerIds().split(",")));
            }
        }

        return hmIssueReceiptRecordsVo;
    }

    /**
     * 分页查询出入库记录列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     *
     * @return 出入库记录分页列表
     */
    @Override
    public TableDataInfo<HmIssueReceiptRecordsVo> queryPageList(HmIssueReceiptRecordsBo bo, PageQuery pageQuery)
    {
        LambdaQueryWrapper<HmIssueReceiptRecords> lqw = buildQueryWrapper(bo);
        Page<HmIssueReceiptRecordsVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的出入库记录列表
     *
     * @param bo 查询条件
     *
     * @return 出入库记录列表
     */
    @Override
    public List<HmIssueReceiptRecordsVo> queryList(HmIssueReceiptRecordsBo bo)
    {
        LambdaQueryWrapper<HmIssueReceiptRecords> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<HmIssueReceiptRecords> buildQueryWrapper(HmIssueReceiptRecordsBo bo)
    {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<HmIssueReceiptRecords> lqw = Wrappers.lambdaQuery();
        List<RoleDTO> roles = LoginHelper.getLoginUser().getRoles();
        List<String> roleNames = roles.stream().map(RoleDTO::getRoleKey).toList();
        lqw.eq(bo.getRecordProductId() != null && bo.getRecordStartLocation() != null, HmIssueReceiptRecords::getRecordProductId, bo.getRecordProductId());
        lqw.eq(bo.getRecordId() != null, HmIssueReceiptRecords::getRecordId, bo.getRecordId());
        lqw.like(StringUtils.isNotBlank(bo.getRecordProductName()), HmIssueReceiptRecords::getRecordProductName, bo.getRecordProductName());
        lqw.eq(bo.getRecordNum() != null, HmIssueReceiptRecords::getRecordNum, bo.getRecordNum());
        lqw.eq(StringUtils.isNotBlank(bo.getRecordType()), HmIssueReceiptRecords::getRecordType, bo.getRecordType());
        lqw.eq(bo.getRecordStartLocation() != null, HmIssueReceiptRecords::getRecordStartLocation, bo.getRecordStartLocation());
        lqw.eq(bo.getRecordEndLocation() != null, HmIssueReceiptRecords::getRecordEndLocation, bo.getRecordEndLocation());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), HmIssueReceiptRecords::getStatus, bo.getStatus());
        if (!LoginHelper.isAdmin() && bo.getRecordStartLocation() == null && !roleNames.contains("warehouse-manage") && !roleNames.contains("dept-manage"))
        {
            // 修改条件组合逻辑，使用括号明确优先级
            lqw.and(wrapper -> wrapper.eq(HmIssueReceiptRecords::getRecordStartLocation, LoginHelper.getDeptId())
                    .eq(bo.getRecordProductId() != null, HmIssueReceiptRecords::getRecordProductId, bo.getRecordProductId()))
                .or(wrapper -> wrapper.eq(HmIssueReceiptRecords::getRecordEndLocation, LoginHelper.getDeptId())
                    .in(HmIssueReceiptRecords::getRecordType, ReceiptIssueRecordTypeEnum.INBOUND.getCode())
                    .eq(bo.getRecordProductId() != null, HmIssueReceiptRecords::getRecordProductId, bo.getRecordProductId()));
        }

        lqw.orderByDesc(HmIssueReceiptRecords::getCreateTime);
        return lqw;
    }

    /**
     * 新增出入库记录
     *
     * @param bo 出入库记录
     *
     * @return 是否新增成功
     */

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean insertByBo(HmIssueReceiptRecordsBo bo)
    {
        try
        {
            HmIssueReceiptRecords add = MapstructUtils.convert(bo, HmIssueReceiptRecords.class);

            // 获取产品类型信息
            Boolean isCommercialProduct = hmProductService.isCommercialProduct(bo.getRecordProductId()); // 产品
            Boolean isGiftProduct = hmProductService.isGiftProduct(bo.getRecordProductId());  // 赠品

            // 设置记录产品类型
            if (Boolean.TRUE.equals(isCommercialProduct) && Boolean.TRUE.equals(isGiftProduct)) {
                add.setRecordProductType("CP,ZP"); // 如果产品同时是商品和赠品
            } else if (Boolean.TRUE.equals(isCommercialProduct)) {
                add.setRecordProductType("CP");
            } else if (Boolean.TRUE.equals(isGiftProduct)) {
                add.setRecordProductType("ZP");
            } else {
                throw new ServiceException("产品ID: " + bo.getRecordProductId() + " 既不是商品产品也不是赠品产品，无法创建出入库记录。");
            }

            // 获取产品名称
            String productName = hmProductService.queryById(bo.getRecordProductId()).getProductName(); // 通过Service获取产品名称
            add.setRecordProductName(productName); // 设置产品名称

            // 查询店长信息
            List<SysUserVo> sysUserVos = List.of();
            // 查询库管信息
            List<SysUserVo> warehouseVo = List.of();
            if (add != null)
            {
                add.setStatus("WCL"); // 默认状态未处理
                if (ReceiptIssueRecordTypeEnum.EMPLOYEE_BENEFITS.getCode().equals(bo.getRecordType()))
                {
                    // 员工福利
                    add.setUserOrCustomerIds(String.join(",", bo.getEmployeeIds()));
                    add.setRecordNum(bo.getRecordNum().multiply(BigDecimal.valueOf(bo.getEmployeeIds().size())));
                    bo.setRecordNum(add.getRecordNum());
                    List<SysUserVo> sysUserVos1 = deptService.selectUserListByDeptId(Long.valueOf(bo.getRecordStartLocation()));
                    if (ObjectUtil.isNotEmpty(sysUserVos1))
                    {
                        // 说明为多店长
                        sysUserVos = sysUserVos1;
                    }
                    else
                    {
                        // 单店长
                        sysUserVos = deptService.selectUserListByDeptIdAndRoleId(Long.valueOf(bo.getRecordStartLocation()), 1869282439378976770L);// 角色对应为店长
                    }
                    warehouseVo = deptService.selectUserListByDeptIdAndRoleId(Long.valueOf(bo.getRecordStartLocation()), 1877229192800808961L);
                }
                else if (ReceiptIssueRecordTypeEnum.CUSTOMER_GIFTS.getCode().equals(bo.getRecordType()))
                {
                    // 客户赠品
                    add.setUserOrCustomerIds(String.join(",", bo.getCustomerIds()));
                    add.setRecordNum(bo.getRecordNum().multiply(BigDecimal.valueOf(bo.getCustomerIds().size())));
                    bo.setRecordNum(add.getRecordNum());
                    List<SysUserVo> sysUserVos1 = deptService.selectUserListByDeptId(Long.valueOf(bo.getRecordStartLocation()));
                    if (ObjectUtil.isNotEmpty(sysUserVos1))
                    {
                        // 说明为多店长
                        sysUserVos = sysUserVos1;
                    }
                    else
                    {
                        // 单店长
                        sysUserVos = deptService.selectUserListByDeptIdAndRoleId(Long.valueOf(bo.getRecordStartLocation()), 1869282439378976770L);// 角色对应为店长
                    }
                    warehouseVo = deptService.selectUserListByDeptIdAndRoleId(Long.valueOf(bo.getRecordStartLocation()), 1877229192800808961L);
                }
                else if (ReceiptIssueRecordTypeEnum.FRINGE_MARKET.getCode().equals(bo.getRecordType()))
                {
                    // 外围市场
                    bo.setRecordEndLocation(null);
                    if (LoginHelper.isAdmin())
                    {
                        add.setStatus("TG");
                    }

                }
                else if (ReceiptIssueRecordTypeEnum.OUTBOUND.getCode().equals(bo.getRecordType()) || ReceiptIssueRecordTypeEnum.SELF_ADDED_RECEIPT.getCode().equals(bo.getRecordType()) || ReceiptIssueRecordTypeEnum.INBOUND.getCode().equals(bo.getRecordType())) {
                    // 出库、自增入库、跨店入库只针对商品产品
                    List<SysUserVo> sysUserVos1 = deptService.selectUserListByDeptId(Long.valueOf(bo.getRecordEndLocation()));
                    if (ObjectUtil.isNotEmpty(sysUserVos1))
                    {
                        // 说明为多店长
                        sysUserVos = sysUserVos1;
                    }
                    else
                    {
                        // 单店长
                        sysUserVos = deptService.selectUserListByDeptIdAndRoleId(Long.valueOf(bo.getRecordEndLocation()), 1869282439378976770L);// 角色对应为店长
                    }
                    warehouseVo = deptService.selectUserListByDeptIdAndRoleId(Long.valueOf(bo.getRecordEndLocation()), 1877229192800808961L);
                } else {
                    throw new ServiceException("未知出入库记录类型或产品类型不匹配。");
                }
            }
            // 出入库前逻辑
            validEntityBeforeSave(bo);
            // 查询仓库名称
            if(bo.getRecordStartLocation() != null){
                add.setRecordStartLocationName(deptService.selectDeptById(Long.valueOf(bo.getRecordStartLocation())).getDeptName());
            }
            if(bo.getRecordEndLocation() != null){
                add.setRecordEndLocationName(deptService.selectDeptById(Long.valueOf(bo.getRecordEndLocation())).getDeptName());
            }
            boolean flag = baseMapper.insert(add) > 0;
            if (flag)
            {
                bo.setRecordId(add.getRecordId());
            }
            if( Boolean.FALSE.equals(bo.getIsAgain())){

                // 出库逻辑
                if (bo.getRecordType().equals(ReceiptIssueRecordTypeEnum.OUTBOUND.getCode()))
                {
                    SysDeptVo sysDeptVoStart = deptService.selectDeptById(Long.valueOf(bo.getRecordStartLocation()));
                    SysDeptVo sysDeptVoEnd = deptService.selectDeptById(Long.valueOf(bo.getRecordEndLocation()));
                    HmTodoItemsBo hmTodoItemsBo = new HmTodoItemsBo();
                    hmTodoItemsBo.setTodoType(ToDoTypeEnum.RECEIPT.getCode()); // 入库提醒
                    hmTodoItemsBo.setTodoDesc(sysDeptVoStart.getDeptName() + " -> " + sysDeptVoEnd.getDeptName() + " 商品:" + productName + ",数量:" + bo.getRecordNum());
                    hmTodoItemsBo.setRemark(bo.getRemark());
                    hmTodoItemsBo.setCreateType("1"); // 系统生成
                    if (add != null)
                    {
                        hmTodoItemsBo.setTodoOutboundOrder(add.getRecordId()); // 出库单
                    }

                    // 设置提交人信息（当前登录人）
                    hmTodoItemsBo.setSubmitterId(LoginHelper.getUserId());
                    hmTodoItemsBo.setSubmitterName(LoginHelper.getUsername());

                    if (ObjectUtil.isNotEmpty(warehouseVo))
                    {
                        hmTodoItemsBo.setTodoPersonId(warehouseVo.get(0).getUserId());
                        hmTodoItemsBo.setTodoPersonName(warehouseVo.get(0).getNickName());
                        hmTodoItemsBo.setTodoStockDept(warehouseVo.get(0).getDeptId());
                        // 设置审核人（待办人即审核人）
                        hmTodoItemsBo.setApproverId(warehouseVo.get(0).getUserId());
                        hmTodoItemsBo.setApproverName(warehouseVo.get(0).getNickName());
                    }
                    else
                    {

                        if (ObjectUtil.isNotEmpty(sysUserVos))
                        {
                            hmTodoItemsBo.setTodoPersonId(sysUserVos.get(0).getUserId());
                            hmTodoItemsBo.setTodoPersonName(sysUserVos.get(0).getNickName());
                            hmTodoItemsBo.setTodoStockDept(sysUserVos.get(0).getDeptId());
                            // 设置审核人（待办人即审核人）
                            hmTodoItemsBo.setApproverId(sysUserVos.get(0).getUserId());
                            hmTodoItemsBo.setApproverName(sysUserVos.get(0).getNickName());

                        }
                        else
                        {
                            // 默认给超级管理员
                            hmTodoItemsBo.setTodoPersonId(1L);
                            hmTodoItemsBo.setTodoPersonName("超级管理员");
                            hmTodoItemsBo.setRemark("尚未找到对应店铺的店长");
                            // 设置审核人为超级管理员
                            hmTodoItemsBo.setApproverId(1L);
                            hmTodoItemsBo.setApproverName("超级管理员");
                        }
                    }

                    hmTodoItemsService.insertByBo(hmTodoItemsBo);

                }
                // 自增入库逻辑
                if (bo.getRecordType().equals(ReceiptIssueRecordTypeEnum.SELF_ADDED_RECEIPT.getCode()))
                {
                    // 判断自增入库的目标点是否为仓库
                    // 主动入库生成一条代办数据给店长,店长确认后正常入库
                    // 当前操作人名称
                    SysUserVo sysUserVo = userService.selectUserById(LoginHelper.getUserId());
                    HmTodoItemsBo hmTodoItemsBo = new HmTodoItemsBo();
                    hmTodoItemsBo.setTodoType(ToDoTypeEnum.RECEIPT.getCode()); // 入库提醒
                    hmTodoItemsBo.setTodoDesc(sysUserVo.getNickName() + "提交店铺商品入库,产品:" + productName + ",数量:" + bo.getRecordNum());
                    hmTodoItemsBo.setCreateType("1"); // 系统生成
                    hmTodoItemsBo.setRemark(bo.getRemark());
                    // 入库单
                    if (add != null)
                    {
                        hmTodoItemsBo.setTodoWarehouseReceipt(add.getRecordId());
                    }

                    // 设置提交人信息（当前登录人）
                    hmTodoItemsBo.setSubmitterId(LoginHelper.getUserId());
                    hmTodoItemsBo.setSubmitterName(LoginHelper.getUsername());

                    if (ObjectUtil.isNotEmpty(sysUserVos))
                    {
                        hmTodoItemsBo.setTodoPersonId(sysUserVos.get(0).getUserId());
                        hmTodoItemsBo.setTodoPersonName(sysUserVos.get(0).getNickName());
                        hmTodoItemsBo.setTodoStockDept(sysUserVos.get(0).getDeptId());
                        // 设置审核人
                        hmTodoItemsBo.setApproverId(sysUserVos.get(0).getUserId());
                        hmTodoItemsBo.setApproverName(sysUserVos.get(0).getNickName());
                    }
                    else
                    {
                        SysUserVo sysUser = userService.selectUserById(1869281362818580481L); // TODO: 硬编码角色ID
                        // 默认给超级管理员
                        hmTodoItemsBo.setTodoPersonId(sysUser.getUserId()); // 林主管id
                        hmTodoItemsBo.setTodoPersonName(sysUser.getNickName());
                        // 设置审核人
                        hmTodoItemsBo.setApproverId(sysUser.getUserId());
                        hmTodoItemsBo.setApproverName(sysUser.getNickName());
                    }
                    hmTodoItemsService.insertByBo(hmTodoItemsBo);

                }
                // 员工福利发放逻辑
                if (bo.getRecordType().equals(ReceiptIssueRecordTypeEnum.EMPLOYEE_BENEFITS.getCode()))
                {
                    // 生成一条待办数据给店长,店长确认后正常出库发放
                    // 当前操作人名称
                    SysUserVo sysUserVo = userService.selectUserById(LoginHelper.getUserId());
                    HmTodoItemsBo hmTodoItemsBo = new HmTodoItemsBo();
                    hmTodoItemsBo.setTodoType(ToDoTypeEnum.EMPLOYEE_BENEFITS.getCode()); // 员工福利
                    hmTodoItemsBo.setTodoDesc(sysUserVo.getNickName() + "提交员工福利发放,产品:" + productName + ",总数量:" + bo.getRecordNum().multiply(BigDecimal.valueOf(bo.getEmployeeIds().size())) + ",总人数:" + bo.getEmployeeIds().size());
                    hmTodoItemsBo.setCreateType("1"); // 系统生成
                    hmTodoItemsBo.setRemark(bo.getRemark());
                    // 入库单
                    if (add != null)
                    {
                        hmTodoItemsBo.setTodoOutboundOrder(add.getRecordId()); // 设置为出库
                    }

                    // 设置提交人信息（当前登录人）
                    hmTodoItemsBo.setSubmitterId(LoginHelper.getUserId());
                    hmTodoItemsBo.setSubmitterName(LoginHelper.getUsername());

                    if (ObjectUtil.isNotEmpty(sysUserVos))
                    {
                        hmTodoItemsBo.setTodoPersonId(sysUserVos.get(0).getUserId());
                        hmTodoItemsBo.setTodoPersonName(sysUserVos.get(0).getNickName());
                        hmTodoItemsBo.setTodoStockDept(sysUserVos.get(0).getDeptId());
                        // 设置审核人
                        hmTodoItemsBo.setApproverId(sysUserVos.get(0).getUserId());
                        hmTodoItemsBo.setApproverName(sysUserVos.get(0).getNickName());
                        hmTodoItemsService.insertByBo(hmTodoItemsBo);
                    }
                    else
                    {
                        throw new RuntimeException("用户信息获取失败");
                    }
                }
                // 赠品发放逻辑
                if (bo.getRecordType().equals(ReceiptIssueRecordTypeEnum.CUSTOMER_GIFTS.getCode()))
                {
                    // 生成一条待办数据给店长,店长确认后正常出库发放
                    // 当前操作人名称
                    SysUserVo sysUserVo = userService.selectUserById(LoginHelper.getUserId());
                    HmTodoItemsBo hmTodoItemsBo = new HmTodoItemsBo();
                    hmTodoItemsBo.setTodoType(ToDoTypeEnum.CUSTOMER_GIFTS.getCode()); // 客户赠品发放
                    hmTodoItemsBo.setTodoDesc(sysUserVo.getNickName() + "提交客户赠品发放,产品:" + productName + ",数量:" + bo.getRecordNum() + ",总人数:" + bo.getCustomerIds()
                        .size());
                    hmTodoItemsBo.setRemark(bo.getRemark());
                    hmTodoItemsBo.setCreateType("1"); // 系统生成
                    // 入库单
                    if (add != null)
                    {
                        hmTodoItemsBo.setTodoOutboundOrder(add.getRecordId()); // 设置为出库
                    }

                    // 设置提交人信息（当前登录人）
                    hmTodoItemsBo.setSubmitterId(LoginHelper.getUserId());
                    hmTodoItemsBo.setSubmitterName(LoginHelper.getUsername());

                    if (ObjectUtil.isNotEmpty(sysUserVos))
                    {
                        hmTodoItemsBo.setTodoPersonId(sysUserVos.get(0).getUserId());
                        hmTodoItemsBo.setTodoPersonName(sysUserVos.get(0).getNickName());
                        hmTodoItemsBo.setTodoStockDept(sysUserVos.get(0).getDeptId());
                        // 设置审核人
                        hmTodoItemsBo.setApproverId(sysUserVos.get(0).getUserId());
                        hmTodoItemsBo.setApproverName(sysUserVos.get(0).getNickName());
                        hmTodoItemsService.insertByBo(hmTodoItemsBo);
                    }
                    else
                    {
                        throw new RuntimeException("用户信息获取失败");
                    }
                }
                // 外围市场逻辑
                if (bo.getRecordType().equals(ReceiptIssueRecordTypeEnum.FRINGE_MARKET.getCode()))
                {
                    // 判断当前登录人角色是否为admin,若不是则需要提交给林主管一个审核
                    if (!LoginHelper.isAdmin())
                    {
                        // 当前操作人名称
                        SysUserVo sysUserVo = userService.selectUserById(LoginHelper.getUserId());
                        SysUserVo sysUser = userService.selectUserById(1869281362818580481L); // TODO: 硬编码角色ID
                        HmTodoItemsBo hmTodoItemsBo = new HmTodoItemsBo();
                        hmTodoItemsBo.setTodoType(ToDoTypeEnum.FRINGE_MARKET.getCode()); // 客户赠品发放
                        hmTodoItemsBo.setTodoDesc(sysUserVo.getNickName() + "提交外围市场出货,产品:" + productName + ",数量:" + bo.getRecordNum() + ",目的地:" + bo.getPeripheralMarket());
                        hmTodoItemsBo.setCreateType("1"); // 系统生成
                        hmTodoItemsBo.setRemark(bo.getRemark());
                        // 出库
                        if (add != null)
                        {
                            hmTodoItemsBo.setTodoOutboundOrder(add.getRecordId()); // 设置为出库
                        }

                        // 设置提交人信息（当前登录人）
                        hmTodoItemsBo.setSubmitterId(LoginHelper.getUserId());
                        hmTodoItemsBo.setSubmitterName(LoginHelper.getUsername());

                        if (ObjectUtil.isNotEmpty(sysUser))
                        {
                            hmTodoItemsBo.setTodoPersonId(sysUser.getUserId()); // 林主管id
                            hmTodoItemsBo.setTodoPersonName(sysUser.getNickName());
                            hmTodoItemsBo.setTodoStockDept(sysUser.getDeptId());
                            // 设置审核人
                            hmTodoItemsBo.setApproverId(sysUser.getUserId());
                            hmTodoItemsBo.setApproverName(sysUser.getNickName());
                            hmTodoItemsService.insertByBo(hmTodoItemsBo);
                        }
                        else
                        {
                            throw new RuntimeException("用户信息获取失败");
                        }
                    }
                    else
                    {
                        HmStockVo hmStockOutVo = hmStockService.queryByProductIdAndDeptId(bo.getRecordProductId(), Long.valueOf(bo.getRecordStartLocation()));
                        if (ObjectUtil.isEmpty(hmStockOutVo) || hmStockOutVo.getStockNum().compareTo(bo.getRecordNum()) < 0)
                        {
                            throw new ServiceException("出库仓库库存不足,无法完成入库操作");
                        }
                        HmStock hmStockBo = new HmStock();
                        // 库存数量
                        hmStockBo.setStockNum(hmStockOutVo.getStockNum().subtract(bo.getRecordNum()));
                        // 更新的库存id
                        hmStockBo.setStockId(hmStockOutVo.getStockId());
                        stockMapper.updateById(hmStockBo);

                        // 出库变更记录
                        HmStockChangeBo hmStockChangeBo = new HmStockChangeBo();
                        hmStockChangeBo.setStockId(hmStockBo.getStockId()); // 库存id
                        hmStockChangeBo.setChangeType(StockChangeTypeEnum.FRINGE_MARKET.getCode()); // 外围市场出库
                        hmStockChangeBo.setChangeInfo(StockChangeTypeEnum.FRINGE_MARKET.getDescription()); // 变更详情
                        hmStockChangeBo.setChangeNum(bo.getRecordNum());// 变更数量
                        hmStockChangeBo.setChangeTime(new Date()); // 变更时间
                        hmStockChangeBo.setProductId(String.valueOf(bo.getRecordProductId())); // 变更商品id
                        hmStockChangeBo.setRecordStartLocation(bo.getRecordStartLocation()); // 出库地
                        hmStockChangeBo.setRecordEndLocationName(bo.getPeripheralMarket()); // 入库地
                        hmStockChangeBo.setRemark(String.format("入库地:%s", bo.getPeripheralMarket()));
                        hmStockChangeServiceImpl.insertByBo(hmStockChangeBo);

                    }
                }
            }


            return flag;
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * 修改出入库记录(驳回再次提交)
     *
     * @param bo 出入库记录
     *
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(HmIssueReceiptRecordsBo bo)
    {
        HmIssueReceiptRecords update = MapstructUtils.convert(bo, HmIssueReceiptRecords.class);
        // 若状态为撤回时,不执行以下方法
        validEntityBeforeSave(bo);

        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(HmIssueReceiptRecordsBo entity)
    {
        // 获取产品类型信息
        Boolean isCommercialProduct = hmProductService.isCommercialProduct(entity.getRecordProductId());
        Boolean isGiftProduct = hmProductService.isGiftProduct(entity.getRecordProductId());

        // 校验产品是否是商品或赠品
        if (Boolean.FALSE.equals(isCommercialProduct) && Boolean.FALSE.equals(isGiftProduct)) {
            throw new ServiceException("产品ID: " + entity.getRecordProductId() + " 既不是商品产品也不是赠品产品，无法进行出入库操作。");
        }


        //TODO 校验当前出库产品所在仓库的库存数量是否大于等于本次出库数量,若大于则不允许出库操作,若小于则更新对应库存数量,更新为总库存量-当前出库数量
        if (!entity.getRecordType().isEmpty())
        {

            // 出库 or 客户赠品发放 or 员工福利发放 or 外围市场
            if (ReceiptIssueRecordTypeEnum.OUTBOUND.getCode().equals(entity.getRecordType()) || ReceiptIssueRecordTypeEnum.CUSTOMER_GIFTS.getCode()
                .equals(entity.getRecordType()) || ReceiptIssueRecordTypeEnum.EMPLOYEE_BENEFITS.getCode()
                .equals(entity.getRecordType()) || ReceiptIssueRecordTypeEnum.FRINGE_MARKET.getCode().equals(entity.getRecordType()))
            {

                // 查询当前出库仓库的出库商品库存数量 //TODO 目前查询的是当前出库仓库
                HmStockVo hmStockVo = hmStockService.queryByProductIdAndDeptId(entity.getRecordProductId(), Long.valueOf(entity.getRecordStartLocation()));
                if (ObjectUtil.isEmpty(hmStockVo) || hmStockVo.getStockNum().compareTo(entity.getRecordNum()) < 0)
                {
                    throw new ServiceException("当前仓库库存不足");
                }
            }
            // 若为驳回后再次提交,则更新对应的代办
            if (Boolean.TRUE.equals(entity.getIsAgain()))
            {
                // 设置entity状态为未处理
                if (!"WCL".equals(entity.getStatus()))
                {
                    entity.setStatus("WCL");
                }
                // 查询当前记录的代办事项
                HmTodoItemsBo hmTodoItemsBo = new HmTodoItemsBo();
                hmTodoItemsBo.setStatus(TodoItemStatus.REJECTED.getCode()); // 已驳回

                if (ReceiptIssueRecordTypeEnum.OUTBOUND.getCode().equals(entity.getRecordType()) || ReceiptIssueRecordTypeEnum.EMPLOYEE_BENEFITS.getCode()
                    .equals(entity.getRecordType()) || ReceiptIssueRecordTypeEnum.CUSTOMER_GIFTS.getCode()
                    .equals(entity.getRecordType()) || ReceiptIssueRecordTypeEnum.FRINGE_MARKET.getCode().equals(entity.getRecordType()))
                {
                    // 出库 or 员工福利 or 客户赠品 or 外围市场
                    hmTodoItemsBo.setTodoOutboundOrder(entity.getRecordId()); // 出库单
                    updateTodoItem(entity, hmTodoItemsBo);
                }
                else if (ReceiptIssueRecordTypeEnum.SELF_ADDED_RECEIPT.getCode().equals(entity.getRecordType()))
                {
                    // 自增入库
                    // 查询当前记录的代办事项
                    hmTodoItemsBo.setTodoWarehouseReceipt(entity.getRecordId()); // 入库单
                    updateTodoItem(entity, hmTodoItemsBo);
                }

            }
        }
    }

    private void updateTodoItem(HmIssueReceiptRecordsBo entity, HmTodoItemsBo hmTodoItemsBo)
    {
        // 自增入库
        SysUserVo sysUserVo = userService.selectUserById(LoginHelper.getUserId());
        List<HmTodoItemsVo> hmTodoItemsVos = DataPermissionHelper.ignore(() -> hmTodoItemsService.queryList(hmTodoItemsBo));
        Optional.ofNullable(hmTodoItemsVos).orElseThrow(() -> new ServiceException("当前记录不存在")).forEach(item ->
        {
            HmTodoItemsBo updateBo = new HmTodoItemsBo();
            BeanUtils.copyProperties(item, updateBo);
            // 产品名称
            String productName = productService.selectProductNameById(entity.getRecordProductId());
            if (ReceiptIssueRecordTypeEnum.OUTBOUND.getCode().equals(entity.getRecordType()) || ReceiptIssueRecordTypeEnum.EMPLOYEE_BENEFITS.getCode()
                .equals(entity.getRecordType()) || ReceiptIssueRecordTypeEnum.CUSTOMER_GIFTS.getCode().equals(entity.getRecordType()))
            {
                if (ReceiptIssueRecordTypeEnum.OUTBOUND.getCode().equals(entity.getRecordType()))
                {
                    // 出库
                    SysDeptVo sysDeptVoStart = deptService.selectDeptById(Long.valueOf(entity.getRecordStartLocation()));
                    SysDeptVo sysDeptVoEnd = deptService.selectDeptById(Long.valueOf(entity.getRecordEndLocation()));
                    updateBo.setTodoDesc(sysDeptVoStart.getDeptName() + " -> " + sysDeptVoEnd.getDeptName() + " 商品:" + productName + ",数量:" + entity.getRecordNum());
                }
                else if (ReceiptIssueRecordTypeEnum.CUSTOMER_GIFTS.getCode().equals(entity.getRecordType()))
                {
                    // 客户赠品
                    updateBo.setTodoDesc(sysUserVo.getNickName() + "提交客户赠品发放,产品:" + productName + ",数量:" + entity.getRecordNum() + ",总人数:" + entity.getCustomerIds()
                        .size());
                }
                else
                {
                    // 员工福利
                    updateBo.setTodoDesc(sysUserVo.getNickName() + "提交员工福利发放,产品:" + productName + ",数量:" + entity.getRecordNum() + ",总人数:" + entity.getEmployeeIds()
                        .size());
                }

            }
            else if (ReceiptIssueRecordTypeEnum.SELF_ADDED_RECEIPT.getCode().equals(entity.getRecordType()))
            {
                updateBo.setTodoDesc(sysUserVo.getNickName() + "提交店铺商品入库,产品:" + productName + ",数量:" + entity.getRecordNum());
            }

            updateBo.setStatus(TodoItemStatus.UNFINISHED.getCode());
            updateBo.setIsAgain(entity.getIsAgain());
            hmTodoItemsService.processingAgent(updateBo);
        });
    }

    /**
     * 校验并批量删除出入库记录信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     *
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid)
    {
        if (isValid)
        {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
}
